home *** CD-ROM | disk | FTP | other *** search
- /*
- * Yamana's Otomeza Plug-in Tool
- * モザイク
- *
- * 1995.07.30 乙女座へ移植
- * 1995.08.13 点モード追加
- *
- *
- */
- #include "otome_pi.h"
-
- const char longname[] = "EFFECT: モザイク";
- int cnfg_max = 3;
- PI_CNFG cnfg[] =
- { /* 1234567890123456 ,min,max,def,set */
- { "速い 高品位? 丸", 0, 2, 0, 0 },
- { "横サイズ" , 1, 16, 4, 4 },
- { "縦サイズ" , 1, 16, 4, 4 },
- };
-
- #define USE_ENV PI_SET_ENV
- #define USE_TYPE PI_EFFC_ALORSL
- #include "otome_pi.c"
-
- /********************************/
-
- void set_vramWidth( vramWidth, xs, pix )
- int *vramWidth;
- int xs,pix;
- {
- if( pix < 8 ) *vramWidth = (xs+7)& 0xfff8;
- else if( pix ==8 ) *vramWidth = (xs );
- else if( pix > 8 ) *vramWidth = (xs*2);
- }
-
- /********************************/
-
- void MosaicEasy( buf, fr, xs,ys )
- char *buf;
- FRAME *fr;
- int xs,ys;
- {
- struct
- { char *addr;
- short ds;
- short sx,sy,ex,ey;
- short xs,ys;
- }para;
-
- para.addr= buf;
- para.ds = pi_data->ds;
- para.sx = fr->lupx;
- para.sy = fr->lupy;
- para.ex = fr->rdwx;
- para.ey = fr->rdwy;
- para.xs = xs;
- para.ys = ys;
- EGB_getBlockZoom( EgbPtr, ¶ );
- EGB_putBlockZoom( EgbPtr, 0x00, ¶ );
- }
-
- /********************************/
-
- int getFunc16( x,y )
- int x,y;
- {
- return (pi_imge->image[ (x>>1) + y*(pi_imge->size.x>>1) ]
- >>((x & 1)? 4:0)& 0x0f );
- }
- int getFunc256( x,y )
- int x,y;
- {
- return (pi_imge->image[ x + y*(pi_imge->size.x) ])& 0xff;
- }
- /********************************/
-
- #define swap(a,b)\
- { int tmp;\
- tmp=(a);(a)=(b);(b)=tmp;\
- }
-
- #define TILE_XS 8
- #define TILE_YS 2
- #define TILE_X (TILE_XS/8)
- #define TILE_Y TILE_YS
-
- #define TILEPAT1 8
- #define TILEPAT2 4
- #define USE_TILE 0x40
- #define NOT_USE_TILE 0x20
-
- void MosaicNormal( image,buf, fr, xs,ys, xsize,ysize, allsize, pix )
- char *image;
- unsigned int *buf;
- FRAME *fr;
- int xs,ys,xsize,ysize,pix;
- POINT *allsize;
- {
- unsigned int *hist = &buf[ xsize*ysize ];
- int sx,sy,x,y,i,j;
- int pos;
- int mx,my,ch;
- FRAME Box;
- int h1,h2;
- char tile[ 32*32 ];
- int tilepat[] = { 0, 2, 4, 6,
- 9,11,13,15 };
- int (*getpix)();
-
- if( pix==8 ) getpix = getFunc256;
- else getpix = getFunc16;
-
- for( sy=0; sy<ys ; sy+= ysize )
- { for( sx=0; sx<xs ; sx+= xsize )
- {
- MOS_rdpos( &ch, &mx, &my );
- if( ch & MOS_RIGHT ) return;
-
- /* 色番号のヒストグラムを作る */
- h1=h2=(-1);
-
- for( y=0; y<ysize; y++ )
- { for( x=0; x<xsize; x++ )
- {
- pos = x+y*xsize;
- buf [ pos ] = getpix( fr->lupx+sx+x, fr->lupy+sy+y );
- hist[ pos ] = 0;
-
- for( i=0; i<=pos ; i++ )
- { if( buf [i] == buf[pos] ) /* 同じ色? */
- { hist[i]++;
- if( hist[i]>=hist[h1] ) /* 頻度の多い2色 */
- h2=h1, h1=i;
- break;
- }
- }
- }
- }
-
- if( h1<0 ) h1 = 0; /* 全部違う色のときは、何色でもいい! */
- if( h2<0 ) h2 = 1; /* てきとーに処理するべし(^^;) */
-
- if( hist[h1] > hist[h2]*3+1 )
- {
- EGB_paintMode( EgbPtr, NOT_USE_TILE );
- EGB_color( EgbPtr, EGB_PAINTCOL, buf[h1] );
- }
- else /* タイルパターンを作る */
- { j=0;
- if( hist[h1]==hist[h2] ) /* 頻度比 1:1 は市松模様 */
- { pos = TILEPAT1;
-
- /* タイルが汚くならないよう色番号によって位置を決める */
- if( buf[h1]&1 )
- { if( buf[h2]&1 )
- { if( h1>=h2 ) swap( h1,h2 );
- }else
- swap( h1,h2 );
- }/* この処理、はっきり言っていい加減である(^^;) */
-
- }else
- { pos = TILEPAT2; /* 頻度比 1:3 */
-
- /* タイル開始位置をずらす */
- if( buf[h1]&1 )
- { if( buf[h2]&1 )
- { if( h1>=h2 ) j=1;
- }else
- j=1;
- }
- }
-
- if( pix == 8 )
- { for(i=0; i<TILE_XS*TILE_YS; i++ )
- tile[i] = buf[h1];
- for( i=0; i<pos ;i++ )
- tile[ tilepat[i]+j ] = buf[h2];
- }else
- { for(i=0; i<TILE_XS*TILE_YS; i++ )
- tile[i] = (buf[h1]& 0x0f) | (buf[h1]<<4) ;
- for( i=0; i<pos ;i++ )
- { x = (tilepat[i]+j)>>1;
- if( (tilepat[i]+j) & 1 )
- tile[x] = (tile[x] & 0x0f) | (buf[h2]<<4) ;
- else
- tile[x] = (tile[x] & 0xf0) | (buf[h2]) ;
- }
- }
-
- EGB_paintMode ( EgbPtr, USE_TILE );
- EGB_tilePattern( EgbPtr, EGB_PAINTCOL,TILE_X,TILE_Y, tile );
- }
-
- Box.lupx = fr->lupx + sx;
- Box.lupy = fr->lupy + sy;
- Box.rdwx = Box.lupx + xsize-1 ;
- Box.rdwy = Box.lupy + ysize-1 ;
- EGB_rectangle( EgbPtr, &Box );
-
- }
- }
-
- }
-
-
- void MosaicPoint( image,buf, fr, xs,ys, xsize,ysize, allsize, pix )
- char *image;
- unsigned int *buf;
- FRAME *fr;
- int xs,ys,xsize,ysize,pix;
- POINT *allsize;
- {
- unsigned int *hist = &buf[ xsize*ysize ];
- int sx,sy,x,y,i,j;
- int pos;
- int mx,my,ch;
- FRAME Box;
- int h1,h2;
- char tile[ 32*32 ];
- int tilepat[] = { 0, 2, 4, 6,
- 9,11,13,15 };
- int (*getpix)();
-
- if( pix==8 ) getpix = getFunc256;
- else getpix = getFunc16;
-
- for( sy=0; sy<ys ; sy+= ysize )
- { for( sx=0+(sy % (ysize*2))/2 ; sx<xs ; sx+= xsize )
- {
- MOS_rdpos( &ch, &mx, &my );
- if( ch & MOS_RIGHT ) return;
-
- /* 色番号のヒストグラムを作る */
- h1=h2=(-1);
- for( y=0; y<ysize; y++ )
- { for( x=0; x<xsize; x++ )
- {
- pos = x+y*xsize;
- buf [ pos ] = getpix( fr->lupx+sx+x, fr->lupy+sy+y );
- hist[ pos ] = 0;
-
- for( i=0; i<=pos ; i++ )
- { if( buf [i] == buf[pos] ) /* 同じ色? */
- { hist[i]++;
- if( hist[i]>=hist[h1] ) /* 頻度の多い2色 */
- h2=h1, h1=i;
- break;
- }
- }
- }
- }
-
- EGB_paintMode( EgbPtr, NOT_USE_TILE );
- EGB_color( EgbPtr, EGB_PAINTCOL, PI_BACKCOL );
- Box.lupx = fr->lupx + sx;
- Box.lupy = fr->lupy + sy;
- Box.rdwx = Box.lupx + xsize-1 ;
- Box.rdwy = Box.lupy + ysize-1 ;
- EGB_rectangle( EgbPtr, &Box );
-
- if( h1<0 ) h1 = 0; /* 全部違う色のときは、何色でもいい! */
- if( h2<0 ) h2 = 1; /* てきとーに処理するべし(^^;) */
-
- if( hist[h1] > hist[h2]*3+1 )
- {
- EGB_paintMode( EgbPtr, NOT_USE_TILE );
- EGB_color( EgbPtr, EGB_PAINTCOL, buf[h1] );
- }
- else /* タイルパターンを作る */
- { j=0;
- if( hist[h1]==hist[h2] ) /* 頻度比 1:1 は市松模様 */
- { pos = TILEPAT1;
-
- /* タイルが汚くならないよう色番号によって位置を決める */
- if( buf[h1]&1 )
- { if( buf[h2]&1 )
- { if( h1>=h2 ) swap( h1,h2 );
- }else
- swap( h1,h2 );
- }/* この処理、はっきり言っていい加減である(^^;) */
-
- }else
- { pos = TILEPAT2; /* 頻度比 1:3 */
-
- /* タイル開始位置をずらす */
- if( buf[h1]&1 )
- { if( buf[h2]&1 )
- { if( h1>=h2 ) j=1;
- }else
- j=1;
- }
- }
-
- if( pix == 8 )
- { for(i=0; i<TILE_XS*TILE_YS; i++ )
- tile[i] = buf[h1];
- for( i=0; i<pos ;i++ )
- tile[ tilepat[i]+j ] = buf[h2];
- }else
- { for(i=0; i<TILE_XS*TILE_YS; i++ )
- tile[i] = (buf[h1]& 0x0f) | (buf[h1]<<4) ;
- for( i=0; i<pos ;i++ )
- { x = (tilepat[i]+j)>>1;
- if( (tilepat[i]+j) & 1 )
- tile[x] = (tile[x] & 0x0f) | (buf[h2]<<4) ;
- else
- tile[x] = (tile[x] & 0xf0) | (buf[h2]) ;
- }
- }
-
- EGB_paintMode ( EgbPtr, USE_TILE );
- EGB_tilePattern( EgbPtr, EGB_PAINTCOL,TILE_X,TILE_Y, tile );
- }
-
- Box.lupx = fr->lupx + sx + xsize/2-1 ;
- Box.lupy = fr->lupy + sy + ysize/2-1 ;
- Box.rdwx = xsize/2;
- Box.rdwy = ysize/2;
- EGB_ellipse( EgbPtr, &Box );
-
- }
- }
-
- }
-
-
-
- /* 32K色だと楽だな~ */
-
- void MosaicNormal32K( image, mode, fr, xs,ys, xsize,ysize, allsize )
- char *image;
- int mode;
- FRAME *fr;
- int xs,ys,xsize,ysize;
- POINT *allsize;
- {
- int sx,sy,x,y, ss;
- int pos,tmp;
- int mx,my,ch;
- FRAME Box;
- unsigned int r,g,b;
-
- // clock_t t;
- // t=clock();
-
- for( ss=0,sy=0; sy<ys ; sy+= ysize )
- {
- if( mode==2 ) ss = (sy % (ysize*2))/2;
- for( sx=0+ss ; sx<xs ; sx+= xsize )
- {
- MOS_rdpos( &ch, &mx, &my );
- if( ch & MOS_RIGHT ) return;
-
- r=g=b=0;
- for( y=0; y<ysize; y++ )
- { for( x=0; x<xsize; x++ )
- {
- pos = ((fr->lupx + sx + x)<<1 )
- + (fr->lupy + sy + y)*(allsize->x<<1) ;
-
- tmp = image[ pos ] + (image[ pos+1 ]<<8) ;
- g += ((tmp>>10) & 0x1f);
- r += ((tmp>>5 ) & 0x1f);
- b += ((tmp ) & 0x1f);
- }
- }
- pos = xsize*ysize;
- g /= pos;
- r /= pos;
- b /= pos;
- EGB_paintMode( EgbPtr, NOT_USE_TILE );
-
- Box.lupx = fr->lupx + sx;
- Box.lupy = fr->lupy + sy;
- Box.rdwx = Box.lupx + xsize-1 ;
- Box.rdwy = Box.lupy + ysize-1 ;
-
- if( mode == 1 )
- { EGB_color( EgbPtr, EGB_PAINTCOL, (int)(g<<10 | r<<5 | b ));
- EGB_rectangle( EgbPtr, &Box );
- }else
- { EGB_color( EgbPtr, EGB_PAINTCOL, PI_BACKCOL );
- EGB_rectangle( EgbPtr, &Box );
- EGB_color( EgbPtr, EGB_PAINTCOL, (int)(g<<10 | r<<5 | b ));
-
- Box.lupx = fr->lupx + sx + xsize/2-1 ;
- Box.lupy = fr->lupy + sy + ysize/2-1 ;
- Box.rdwx = xsize/2;
- Box.rdwy = ysize/2;
- EGB_ellipse( EgbPtr, &Box );
- }
- }
- }
-
- // printf("time = %d", clock()-t );
-
- /* EGB_point : clock==850 */
- /* 直接取る : clock==305 */
- }
-
- /********************************/
-
- int APL_exec()
- {
- int mode,xsize,ysize;
- int width,height, xs,ys,vramWidth;
- char *buf;
- int mx,my,ch;
- FRAME fr;
-
- mode = cnfg[0].val; /* 0:高速版 1:高品位版 2:点 */
- xsize = cnfg[1].val; /* Xサイズ */
- ysize = cnfg[2].val; /* Yサイズ */
-
- if( xsize == 1 && ysize == 1 ) return NOERR;
-
- memcpy( &fr, g_para, sizeof( fr ) );
-
- EGB_writePage( EgbPtr, pi_imge->page );
- EGB_viewport ( EgbPtr, &fr );
-
- fr.lupx = (fr.lupx / xsize * xsize);
- fr.lupy = (fr.lupy / ysize * ysize);
- fr.rdwx = (fr.rdwx / xsize * xsize + xsize-1);
- fr.rdwy = (fr.rdwy / ysize * ysize + ysize-1);
-
- width = (fr.rdwx - fr.lupx + 1);
- height = (fr.rdwy - fr.lupy + 1);
- xs = (width +xsize-1)/xsize ;
- ys = (height+ysize-1)/ysize ;
-
- /*******************************/
- if( mode == 0 )
- {
- set_vramWidth( &vramWidth, xs, pi_imge->pix );
-
- if( (buf = PI_MALLOC( vramWidth*ys ))==NULL )
- return PI_ERROR_NO_MEMORY;
-
- MosaicEasy( buf, &fr, xs,ys );
-
- PI_FREE( buf );
- }
- else
- { xs *= xsize;
- ys *= ysize;
-
- if( pi_imge->pix >8 )
- {
- MosaicNormal32K( pi_imge->image, mode,
- &fr, xs,ys, xsize,ysize, &pi_imge->size );
- }
- else
- { if( (buf = PI_MALLOC( xsize*ysize*sizeof(int)*2 ))==NULL )
- return PI_ERROR_NO_MEMORY;
-
- if( mode ==1 )
- MosaicNormal( pi_imge->image, (unsigned int*)buf,
- &fr, xs,ys, xsize,ysize, &pi_imge->size, pi_imge->pix );
- else
- MosaicPoint( pi_imge->image, (unsigned int*)buf,
- &fr, xs,ys, xsize,ysize, &pi_imge->size, pi_imge->pix );
-
- PI_FREE( buf );
- }
- }
-
- do
- { MOS_rdpos( &ch, &mx, &my );
- }while( ch & MOS_RIGHT );
-
-
- return NOERR;
- }
-